using System.Collections.Generic;

namespace PerfectSphere
{
    internal delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);

    internal static class Maths
    {
        public static bool SphericalLocusCheck(float x, float y, float z, float radius)
        {
            return ElipsoidLocusCheck(x, y, z, radius, radius, radius);
        }

        public static bool ElipsoidLocusCheck(float x, float y, float z, float radiusX, float radiusY, float radiusZ)
        {
            return (x * x) / (radiusX * radiusX) + (y * y) / (radiusY * radiusY) + (z * z) / (radiusZ * radiusZ) < 1;
        }

        public static IEnumerable<Block> GetOrthogonalNeighbours(int x, int y, int z)
        {
            yield return new Block(x - 1, y, z);
            yield return new Block(x, y - 1, z);
            yield return new Block(x, y, z - 1);

            yield return new Block(x + 1, y, z);
            yield return new Block(x, y + 1, z);
            yield return new Block(x, y, z + 1);
        }

        public static bool OnSurfaceEdgeCheck(int x, int y, int z, Func<int, int, int, bool> locusCheck)
        {
            int neighboursSet = 0;
            int neighboursNotSet = 0;

            foreach (var block in GetOrthogonalNeighbours(x, y, z))
            {
                if (locusCheck(block.X, block.Y, block.Z))
                    neighboursSet++;
                else
                    neighboursNotSet++;

                if (neighboursSet > 0 && neighboursNotSet > 0)
                    return true;
            }

            return false;
        }
    }
}
